﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Management.Automation.Remoting;
using System.Collections.ObjectModel;

/// <summary>
/// This class is used to executed powershell cmdlets
/// on an remote Exchange 2010 Server and recieving its feedback.
/// - It is used to create the mailbox or mail-enable an account.
/// </summary>
public class PSwithEX
{
	public PSwithEX()
	{
		psCmd = "";
	}
     
    private string psCmd;
    private List<string> psCmdProps = new List<string>();
    
    public string PSCmd
    { 
        get
        {
            return psCmd;
        }
        set
        {
            psCmd = value;
        }
    }
    
    public List<string> PSCmdProps
    {
        get
        {
            return psCmdProps;
        }
        set
        {
            psCmdProps = value;
        }
    }

    public List<string> RunPSCmd(out int retval, ref string objContentMsg)
    {
        retval = 0;      
    
        List<string> rtnLst = new List<string>();            
        
        string ExServer = WbGetParams.ExchangeServerName;
        string psaddr = "http://" + ExServer + "/powershell?serializationLevel=Full";
        System.Uri uri = new Uri(psaddr);                

        Runspace runspace = RunspaceFactory.CreateRunspace();

        PowerShell powershell = PowerShell.Create();
        PSCommand command = new PSCommand();
        command.AddCommand("New-PSSession");
        command.AddParameter("ConfigurationName", "Microsoft.Exchange");
        command.AddParameter("ConnectionUri", uri);
        command.AddParameter("Authentication", "Default");
        PSSessionOption sessionOption = new PSSessionOption();
        sessionOption.SkipCACheck = true;
        sessionOption.SkipCNCheck = true;
        sessionOption.SkipRevocationCheck = true;
        command.AddParameter("SessionOption", sessionOption);

        powershell.Commands = command;

        try
        {
            
            runspace.Open();                      
            powershell.Runspace = runspace;
            Collection<PSSession> result = powershell.Invoke<PSSession>();            

            if (result.Count != 1)
                throw new Exception("Unexpected number of Remote Runspace connections returned.");
                        
            powershell = PowerShell.Create();
            command = new PSCommand();
            command.AddCommand("Set-Variable");
            command.AddParameter("Name", "ra");
            command.AddParameter("Value", result[0]);
            powershell.Commands = command;
            powershell.Runspace = runspace;
            powershell.Invoke();
                        
            powershell = PowerShell.Create();
            command = new PSCommand();
            command.AddScript("Import-PSSession -Session $ra");
            powershell.Commands = command;
            powershell.Runspace = runspace;
            powershell.Invoke();
                        
            powershell = PowerShell.Create();
            command = new PSCommand();
            command.AddScript(psCmd);
            powershell.Commands = command;
            powershell.Runspace = runspace;

            Collection<PSObject> results = new Collection<PSObject>();
            results = powershell.Invoke();

            if (powershell.Streams.Error.Count > 0)
            {
                foreach (ErrorRecord current in powershell.Streams.Error)
                {                                     
                    rtnLst.Add("Exception: " + current.Exception.Message.ToString());
                    rtnLst.Add("Stack Trace: " + current.Exception.StackTrace.ToString());
                }
                powershell.Streams.Error.Clear();
                retval = 1;
            }
            else
            {                
                foreach (PSObject PSresult in results)
                {
                    foreach(var item in psCmdProps)
                    {                        
                        rtnLst.Add(PSresult.Properties[item].Value.ToString());
                    }                    
                }             
                retval = 0;
            }         
        }

        catch (System.Exception ex)
        {
            rtnLst.Add(ex.Message);
            rtnLst.Add(ex.StackTrace);            
            objContentMsg = "exception:";
            retval = 1;
        }

        finally
        {         
            runspace.Dispose();
            runspace = null;            
            powershell.Dispose();
            powershell = null;
        }
                
        return rtnLst;

     }

}